﻿using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Web;
using System.Web.Mvc;

using mvcForum.Core;
using mvcForum.Core.Abstractions.Interfaces;
using mvcForum.Core.Specifications;
using mvcForum.Web.Extensions;
using mvcForum.Web.Interfaces;
using mvcForum.Core.Interfaces.Data;

namespace mvcForum.Web.Helpers {

	public static class TimezoneHelper {
		private const String timeZoneCacheKey = "TimeZone";

		public static DateTime ToLocalDateTime(this DateTimeOffset dt) {
			TimeZoneInfo tzi = GetTimeZoneInfo();
			return TimeZoneInfo.ConvertTimeFromUtc(dt.UtcDateTime, tzi);
		}

		public static DateTime ToLocalDateTime(this DateTime dt) {
			TimeZoneInfo tzi = GetTimeZoneInfo();
			dt = TimeZoneInfo.ConvertTimeFromUtc(dt, tzi);
			return dt;
		}

		public static TimeZoneInfo GetTimeZoneInfo() {
			// Fallback, if everything else fails!
			TimeZoneInfo tzi = TimeZoneInfo.Local;
			try {
				IPerRequestCache cache = DependencyResolver.Current.GetService<IPerRequestCache>();
				Object cachedTimezone = cache.Pull(timeZoneCacheKey);
				// Cached timezone? No need to do alot of work to find it again then!
				if (cachedTimezone != null) {
					tzi = TimeZoneInfo.FindSystemTimeZoneById((String)cachedTimezone);
				}
				else {
					// Let's get the default timezone (if present)
					IConfiguration config = DependencyResolver.Current.GetService<IConfiguration>();
					if (!String.IsNullOrWhiteSpace(config.DefaultTimezone)) {
						try {
							tzi = TimeZoneInfo.FindSystemTimeZoneById(config.DefaultTimezone);
						}
						catch { }
					}

					IWebUserProvider userProvider = DependencyResolver.Current.GetService<IWebUserProvider>();
					IRepository<ForumUser> userRepository = DependencyResolver.Current.GetService<IRepository<ForumUser>>();

					// Authenticated user?
					if (userProvider.Authenticated) {
						ForumUser user = userProvider.ActiveUser;
						//ForumUser user = userRepository.Read(userProvider.CurrentUserId);
						tzi = TimeZoneInfo.FindSystemTimeZoneById(user.Timezone);

						// Cache timezone, it might be needed again in this request!
						cache.Push(timeZoneCacheKey, user.Timezone);
					}
				}
			}
			catch { }

			return tzi;
		}

		public static DateTime ToLocalDateTime(this HtmlHelper html, DateTime dt) {
			return dt.ToLocalDateTime();
		}

		public static IEnumerable<SelectListItem> GetTimeZones(String selectedTimeZone) {
			List<SelectListItem> items = new List<SelectListItem>();
			ReadOnlyCollection<TimeZoneInfo> infos = TimeZoneInfo.GetSystemTimeZones();
			foreach (var tzi in infos) {
				items.Add(new SelectListItem { Text = tzi.DisplayName, Value = tzi.Id, Selected = (tzi.Id == selectedTimeZone) });
			}
			return items;
		}
	}
}